home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / POINT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-21  |  15.7 KB  |  839 lines

  1. /****************************************************************************
  2. *                point.c
  3. *
  4. *  This module implements the point & spot light source primitive.
  5. *
  6. *  from Persistence of Vision(tm) Ray Tracer
  7. *  Copyright 1996 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other 
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If 
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23.  
  24. #include "frame.h"
  25. #include "vector.h"
  26. #include "povproto.h"
  27. #include "point.h"
  28. #include "matrices.h"
  29. #include "objects.h"
  30. #include "povray.h"
  31.  
  32.  
  33.  
  34. /*****************************************************************************
  35. * Local preprocessor defines
  36. ******************************************************************************/
  37.  
  38.  
  39.  
  40. /*****************************************************************************
  41. * Local typedefs
  42. ******************************************************************************/
  43.  
  44.  
  45.  
  46. /*****************************************************************************
  47. * Static functions
  48. ******************************************************************************/
  49.  
  50. static DBL cubic_spline PARAMS(( DBL low,DBL high,DBL pos));
  51. static int  All_Light_Source_Intersections PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
  52. static int  Inside_Light_Source PARAMS((VECTOR point, OBJECT *Object));
  53. static void Light_Source_Normal PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  54. static void Translate_Light_Source PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  55. static void Rotate_Light_Source PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  56. static void Scale_Light_Source PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  57. static void Transform_Light_Source PARAMS((OBJECT *Object, TRANSFORM *Trans));
  58. static void Invert_Light_Source PARAMS((OBJECT *Object));
  59. static void *Copy_Light_Source PARAMS((OBJECT *Object));
  60. static void Destroy_Light_Source PARAMS((OBJECT *Object));
  61.  
  62. /*****************************************************************************
  63. * Local variables
  64. ******************************************************************************/
  65.  
  66. static METHODS Light_Source_Methods =
  67. {
  68.   All_Light_Source_Intersections,
  69.   Inside_Light_Source, Light_Source_Normal,
  70.   Copy_Light_Source,
  71.   Translate_Light_Source, Rotate_Light_Source,
  72.   Scale_Light_Source, Transform_Light_Source, Invert_Light_Source,
  73.   Destroy_Light_Source
  74. };
  75.  
  76.  
  77.  
  78.  
  79.  
  80. /*****************************************************************************
  81. *
  82. * FUNCTION
  83. *
  84. *   All_Light_Source_Intersections
  85. *
  86. * INPUT
  87. *   
  88. * OUTPUT
  89. *   
  90. * RETURNS
  91. *   
  92. * AUTHOR
  93. *
  94. *   POV-Ray Team
  95. *   
  96. * DESCRIPTION
  97. *
  98. *   -
  99. *
  100. * CHANGES
  101. *
  102. *   -
  103. *
  104. ******************************************************************************/
  105.  
  106. static int All_Light_Source_Intersections (Object, Ray, Depth_Stack)
  107. OBJECT *Object;
  108. RAY *Ray;
  109. ISTACK *Depth_Stack;
  110. {
  111.   if (((LIGHT_SOURCE *)Object)->Children != NULL)
  112.   {
  113.     if (Ray_In_Bound (Ray, ((LIGHT_SOURCE *)Object)->Children->Bound))
  114.     {
  115.       if (All_Intersections (((LIGHT_SOURCE *)Object)->Children, Ray, Depth_Stack))
  116.       {
  117.         return(TRUE);
  118.       }
  119.     }
  120.   }
  121.  
  122.   return(FALSE);
  123. }
  124.  
  125.  
  126.  
  127. /*****************************************************************************
  128. *
  129. * FUNCTION
  130. *
  131. *   Inside_Light_Source
  132. *
  133. * INPUT
  134. *   
  135. * OUTPUT
  136. *   
  137. * RETURNS
  138. *   
  139. * AUTHOR
  140. *
  141. *   POV-Ray Team
  142. *   
  143. * DESCRIPTION
  144. *
  145. *   -
  146. *
  147. * CHANGES
  148. *
  149. *   -
  150. *
  151. ******************************************************************************/
  152.  
  153. static int Inside_Light_Source (IPoint, Object)
  154. VECTOR IPoint;
  155. OBJECT *Object;
  156. {
  157.   if (((LIGHT_SOURCE *)Object)->Children != NULL)
  158.   {
  159.     if (Inside_Object (IPoint, ((LIGHT_SOURCE *)Object)->Children))
  160.     {
  161.       return (TRUE);
  162.     }
  163.   }
  164.  
  165.   return (FALSE);
  166. }
  167.  
  168.  
  169.  
  170. /*****************************************************************************
  171. *
  172. * FUNCTION
  173. *
  174. *   Light_Source_Normal
  175. *
  176. * INPUT
  177. *   
  178. * OUTPUT
  179. *   
  180. * RETURNS
  181. *   
  182. * AUTHOR
  183. *
  184. *   POV-Ray Team
  185. *   
  186. * DESCRIPTION
  187. *
  188. *   -
  189. *
  190. * CHANGES
  191. *
  192. *   -
  193. *
  194. ******************************************************************************/
  195.  
  196. static void Light_Source_Normal (Result, Object, Inter)
  197. OBJECT *Object;
  198. VECTOR Result;
  199. INTERSECTION *Inter;
  200. {
  201.   if (((LIGHT_SOURCE *)Object)->Children != NULL)
  202.   {
  203.     Normal (Result, ((LIGHT_SOURCE *)Object)->Children,Inter);
  204.   }
  205. }
  206.  
  207.  
  208.  
  209. /*****************************************************************************
  210. *
  211. * FUNCTION
  212. *
  213. *   Translate_Light_Source
  214. *
  215. * INPUT
  216. *   
  217. * OUTPUT
  218. *   
  219. * RETURNS
  220. *   
  221. * AUTHOR
  222. *
  223. *   POV-Ray Team
  224. *   
  225. * DESCRIPTION
  226. *
  227. *   -
  228. *
  229. * CHANGES
  230. *
  231. *   -
  232. *
  233. ******************************************************************************/
  234.  
  235. static void Translate_Light_Source (Object, Vector, Trans)
  236. OBJECT *Object;
  237. VECTOR Vector;
  238. TRANSFORM *Trans;
  239. {
  240.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Object;
  241.  
  242.   VAddEq (Light->Center, Vector);
  243.   VAddEq (Light->Points_At, Vector);
  244.  
  245.   if (Light->Children != NULL)
  246.   {
  247.     Translate_Object (Light->Children, Vector, Trans);
  248.   }
  249. }
  250.  
  251.  
  252.  
  253. /*****************************************************************************
  254. *
  255. * FUNCTION
  256. *
  257. *   Rotate_Light_Source
  258. *
  259. * INPUT
  260. *   
  261. * OUTPUT
  262. *   
  263. * RETURNS
  264. *   
  265. * AUTHOR
  266. *
  267. *   POV-Ray Team
  268. *   
  269. * DESCRIPTION
  270. *
  271. *   -
  272. *
  273. * CHANGES
  274. *
  275. *   -
  276. *
  277. ******************************************************************************/
  278.  
  279. static void Rotate_Light_Source (Object, Vector, Trans)
  280. OBJECT *Object;
  281. VECTOR Vector;
  282. TRANSFORM *Trans;
  283. {
  284.   Transform_Light_Source(Object, Trans);
  285. }
  286.  
  287.  
  288.  
  289. /*****************************************************************************
  290. *
  291. * FUNCTION
  292. *
  293. *   Scale_Light_Source
  294. *
  295. * INPUT
  296. *   
  297. * OUTPUT
  298. *   
  299. * RETURNS
  300. *   
  301. * AUTHOR
  302. *
  303. *   POV-Ray Team
  304. *   
  305. * DESCRIPTION
  306. *
  307. *   -
  308. *
  309. * CHANGES
  310. *
  311. *   -
  312. *
  313. ******************************************************************************/
  314.  
  315. static void Scale_Light_Source (Object, Vector, Trans)
  316. OBJECT *Object;
  317. VECTOR Vector;
  318. TRANSFORM *Trans;
  319. {
  320.   Transform_Light_Source(Object, Trans);
  321. }
  322.  
  323.  
  324.  
  325. /*****************************************************************************
  326. *
  327. * FUNCTION
  328. *
  329. *   Transform_Light_Source
  330. *
  331. * INPUT
  332. *   
  333. * OUTPUT
  334. *   
  335. * RETURNS
  336. *   
  337. * AUTHOR
  338. *
  339. *   POV-Ray Team
  340. *   
  341. * DESCRIPTION
  342. *
  343. *   -
  344. *
  345. * CHANGES
  346. *
  347. *   -
  348. *
  349. ******************************************************************************/
  350.  
  351. static void Transform_Light_Source (Object, Trans)
  352. OBJECT *Object;
  353. TRANSFORM *Trans;
  354. {
  355.   DBL len;
  356.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Object;
  357.  
  358.   MTransPoint (Light->Center,    Light->Center,    Trans);
  359.   MTransPoint (Light->Points_At, Light->Points_At, Trans);
  360.   MTransPoint (Light->Axis1,     Light->Axis1,     Trans);
  361.   MTransPoint (Light->Axis2,     Light->Axis2,     Trans);
  362.  
  363.   MTransDirection (Light->Direction, Light->Direction, Trans);
  364.  
  365.   /* Make sure direction has unit length. */
  366.  
  367.   VLength(len, Light->Direction);
  368.  
  369.   if (len > EPSILON)
  370.   {
  371.     VInverseScaleEq(Light->Direction, len);
  372.   }
  373.  
  374.   if (Light->Children != NULL)
  375.   {
  376.     Transform_Object (Light->Children, Trans);
  377.   }
  378. }
  379.  
  380.  
  381.  
  382. /*****************************************************************************
  383. *
  384. * FUNCTION
  385. *
  386. *   Invert_Light_Source
  387. *
  388. * INPUT
  389. *   
  390. * OUTPUT
  391. *   
  392. * RETURNS
  393. *   
  394. * AUTHOR
  395. *
  396. *   POV-Ray Team
  397. *   
  398. * DESCRIPTION
  399. *
  400. *   -
  401. *
  402. * CHANGES
  403. *
  404. *   -
  405. *
  406. ******************************************************************************/
  407.  
  408. static void Invert_Light_Source (Object)
  409. OBJECT *Object;
  410. {
  411.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Object;
  412.  
  413.   if (Light->Children != NULL)
  414.   {
  415.     Invert_Object (Light->Children);
  416.   }
  417. }
  418.  
  419.  
  420.  
  421. /*****************************************************************************
  422. *
  423. * FUNCTION
  424. *
  425. *   Create_Light_Source
  426. *
  427. * INPUT
  428. *   
  429. * OUTPUT
  430. *   
  431. * RETURNS
  432. *   
  433. * AUTHOR
  434. *
  435. *   POV-Ray Team
  436. *   
  437. * DESCRIPTION
  438. *
  439. *   -
  440. *
  441. * CHANGES
  442. *
  443. *   -
  444. *
  445. ******************************************************************************/
  446.  
  447. LIGHT_SOURCE *Create_Light_Source ()
  448. {
  449.   int i;
  450.   LIGHT_SOURCE *New;
  451.  
  452.   New = (LIGHT_SOURCE *)POV_MALLOC(sizeof (LIGHT_SOURCE), "light_source");
  453.  
  454.   INIT_OBJECT_FIELDS(New, LIGHT_OBJECT, &Light_Source_Methods)
  455.  
  456.   New->Children = NULL;
  457.  
  458.   Set_Flag(New, NO_SHADOW_FLAG);
  459.  
  460.   Make_Colour(New->Colour,    1.0, 1.0, 1.0);
  461.   Make_Vector(New->Direction, 0.0, 0.0, 0.0);
  462.   Make_Vector(New->Center,    0.0, 0.0, 0.0);
  463.   Make_Vector(New->Points_At, 0.0, 0.0, 1.0);
  464.   Make_Vector(New->Axis1,     0.0, 0.0, 1.0);
  465.   Make_Vector(New->Axis2,     0.0, 1.0, 0.0);
  466.  
  467.   New->Coeff   = 10.0;
  468.   New->Radius  = 0.35;
  469.   New->Falloff = 0.35;
  470.  
  471.   New->Fade_Distance = 0.0;
  472.   New->Fade_Power    = 0.0;
  473.  
  474.   New->Next_Light_Source    = NULL;
  475.   New->Light_Grid           = NULL;
  476.   New->Shadow_Cached_Object = NULL;
  477.  
  478.   New->Light_Type = POINT_SOURCE;
  479.  
  480.   New->Area_Light = FALSE;
  481.   New->Jitter     = FALSE;
  482.   New->Track      = FALSE;
  483.  
  484.   New->Area_Size1 = 0;
  485.   New->Area_Size2 = 0;
  486.  
  487.   New->Adaptive_Level = 100;
  488.  
  489.   New->Atmospheric_Attenuation = FALSE;
  490.   New->Atmosphere_Interaction  = TRUE;
  491.  
  492.   for (i = 0; i < 6; i++)
  493.   {
  494.     New->Light_Buffer[i] = NULL;
  495.   }
  496.  
  497.   return (New);
  498. }
  499.  
  500.  
  501.  
  502. /*****************************************************************************
  503. *
  504. * FUNCTION
  505. *
  506. *   Copy_Light_Source
  507. *
  508. * INPUT
  509. *   
  510. * OUTPUT
  511. *   
  512. * RETURNS
  513. *   
  514. * AUTHOR
  515. *
  516. *   POV-Ray Team
  517. *   
  518. * DESCRIPTION
  519. *
  520. *   -
  521. *
  522. * CHANGES
  523. *
  524. *   -
  525. *
  526. ******************************************************************************/
  527.  
  528. static void *Copy_Light_Source (Old)
  529. OBJECT *Old;
  530. {
  531.   int i, j;
  532.   LIGHT_SOURCE *New;
  533.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Old;
  534.  
  535.   New = Create_Light_Source();
  536.  
  537.   /* Copy light source. */
  538.  
  539.   *New = *(LIGHT_SOURCE *)Old;
  540.  
  541.   New->Next_Light_Source = NULL;
  542.  
  543.   New->Children = Copy_Object (((LIGHT_SOURCE *)Old)->Children);
  544.  
  545.   if (Light->Light_Grid != NULL)
  546.   {
  547.     New->Light_Grid = Create_Light_Grid(Light->Area_Size1, Light->Area_Size2);
  548.  
  549.     for (i = 0; i < Light->Area_Size1; i++)
  550.     {
  551.       for (j = 0; j < Light->Area_Size2; j++)
  552.       {
  553.         Assign_Colour(New->Light_Grid[i][j], Light->Light_Grid[i][j]);
  554.       }
  555.     }
  556.   }
  557.  
  558.   return (New);
  559. }
  560.  
  561.  
  562.  
  563. /*****************************************************************************
  564. *
  565. * FUNCTION
  566. *
  567. *   Destroy_Light_Source
  568. *
  569. * INPUT
  570. *   
  571. * OUTPUT
  572. *   
  573. * RETURNS
  574. *   
  575. * AUTHOR
  576. *
  577. *   POV-Ray Team
  578. *   
  579. * DESCRIPTION
  580. *
  581. *   -
  582. *
  583. * CHANGES
  584. *
  585. *   -
  586. *
  587. ******************************************************************************/
  588.  
  589. static void Destroy_Light_Source (Object)
  590. OBJECT *Object;
  591. {
  592.   int i;
  593.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Object;
  594.  
  595.   if (Light->Light_Grid != NULL)
  596.   {
  597.     for (i = 0; i < Light->Area_Size1; i++)
  598.     {
  599.       POV_FREE(Light->Light_Grid[i]);
  600.     }
  601.  
  602.     POV_FREE(Light->Light_Grid);
  603.   }
  604.  
  605.   Destroy_Object(Light->Children);
  606.  
  607.   POV_FREE(Object);
  608. }
  609.  
  610.  
  611.  
  612. /*****************************************************************************
  613. *
  614. * FUNCTION
  615. *
  616. *   Create_Light_Grid
  617. *
  618. * INPUT
  619. *   
  620. * OUTPUT
  621. *   
  622. * RETURNS
  623. *   
  624. * AUTHOR
  625. *
  626. *   POV-Ray Team
  627. *   
  628. * DESCRIPTION
  629. *
  630. *   -
  631. *
  632. * CHANGES
  633. *
  634. *   -
  635. *
  636. ******************************************************************************/
  637.  
  638. COLOUR **Create_Light_Grid (Size1, Size2)
  639. int Size1, Size2;
  640. {
  641.   int i;
  642.   COLOUR **New;
  643.  
  644.   New = (COLOUR **)POV_MALLOC(Size1 * sizeof (COLOUR *), "area light");
  645.  
  646.   for (i = 0; i < Size1; i++)
  647.   {
  648.     New[i] = (COLOUR *)POV_MALLOC(Size2 * sizeof (COLOUR), "area light");
  649.   }
  650.  
  651.   return (New);
  652. }
  653.  
  654.  
  655.  
  656. /*****************************************************************************
  657. *
  658. * FUNCTION
  659. *
  660. *   cubic_spline
  661. *
  662. * INPUT
  663. *   
  664. * OUTPUT
  665. *   
  666. * RETURNS
  667. *   
  668. * AUTHOR
  669. *
  670. *   POV-Ray Team
  671. *   
  672. * DESCRIPTION
  673. *
  674. *   Cubic spline that has tangents of slope 0 at x == low and at x == high.
  675. *   For a given value "pos" between low and high the spline value is returned.
  676. *
  677. * CHANGES
  678. *
  679. *   -
  680. *
  681. ******************************************************************************/
  682.  
  683. static DBL cubic_spline(low, high, pos)
  684. DBL low, high, pos;
  685. {
  686.   /* Check to see if the position is within the proper boundaries. */
  687.  
  688.   if (pos < low)
  689.   {
  690.     return(0.0);
  691.   }
  692.   else
  693.   {
  694.     if (pos >= high)
  695.     {
  696.       return(1.0);
  697.     }
  698.   }
  699.  
  700.   /* This never happens. [DB] */
  701.  
  702. /*
  703.   if (high == low)
  704.   {
  705.     return(0.0);
  706.   }
  707. */
  708.  
  709.   /* Normalize to the interval [0...1]. */
  710.  
  711.   pos = (pos - low) / (high - low);
  712.  
  713.   /* See where it is on the cubic curve. */
  714.  
  715.   return(3 - 2 * pos) * pos * pos;
  716. }
  717.  
  718.  
  719.  
  720. /*****************************************************************************
  721. *
  722. * FUNCTION
  723. *
  724. *   Attenuate_Light
  725. *
  726. * INPUT
  727. *   
  728. * OUTPUT
  729. *   
  730. * RETURNS
  731. *   
  732. * AUTHOR
  733. *
  734. *   POV-Ray Team
  735. *   
  736. * DESCRIPTION
  737. *
  738. *   -
  739. *
  740. * CHANGES
  741. *
  742. *   Jan 1995 : Added attenuation due to atmospheric scattering and light
  743. *              source distance. Added cylindrical light source. [DB]
  744. *
  745. ******************************************************************************/
  746.  
  747. DBL Attenuate_Light (Light, Ray, Distance)
  748. LIGHT_SOURCE *Light;
  749. RAY *Ray;
  750. DBL Distance;
  751. {
  752.   DBL len, k, costheta;
  753.   DBL Attenuation = 1.0;
  754.   VECTOR P, V1;
  755.  
  756.   /* If this is a spotlight then attenuate based on the incidence angle. */
  757.  
  758.   switch (Light->Light_Type)
  759.   {
  760.     case SPOT_SOURCE:
  761.  
  762.       VDot(costheta, Ray->Direction, Light->Direction);
  763.  
  764.       costheta *= -1.0;
  765.  
  766.       if (costheta > 0.0)
  767.       {
  768.         Attenuation = pow(costheta, Light->Coeff);
  769.  
  770.         /*
  771.          * If there is a soft falloff region associated with the light then
  772.          * do an interpolation of values between the hot center and the
  773.          * direction at which light falls to nothing.
  774.          */
  775.  
  776.         if (Light->Radius > 0.0)
  777.         {
  778.           Attenuation *= cubic_spline(Light->Falloff, Light->Radius, costheta);
  779.         }
  780. /*
  781.         Debug_Info("Atten: %lg\n", Attenuation);
  782. */
  783.       }
  784.       else
  785.       {
  786.         Attenuation = 0.0;
  787.       }
  788.  
  789.       break;
  790.  
  791.     case CYLINDER_SOURCE:
  792.  
  793.       VSub(V1, Ray->Initial, Light->Center);
  794.  
  795.       VDot(k, V1, Light->Direction);
  796.  
  797.       if (k > 0.0)
  798.       {
  799.         VLinComb2(P, 1.0, V1, -k, Light->Direction);
  800.  
  801.         VLength(len, P);
  802.  
  803.         if (len < Light->Falloff)
  804.         {
  805.           len = 1.0 - len / Light->Falloff;
  806.  
  807.           Attenuation = pow(len, Light->Coeff);
  808.  
  809.           if (Light->Radius > 0.0)
  810.           {
  811.             Attenuation *= cubic_spline(1.0 - Light->Radius / Light->Falloff, 1.0, len);
  812.           }
  813.         }
  814.         else
  815.         {
  816.           Attenuation = 0.0;
  817.         }
  818.       }
  819.       else
  820.       {
  821.         Attenuation = 0.0;
  822.       }
  823.  
  824.       break;
  825.   }
  826.  
  827.   if (Attenuation > 0.0)
  828.   {
  829.     /* Attenuate light due to light source distance. */
  830.  
  831.     if ((Light->Fade_Power > 0.0) && (fabs(Light->Fade_Distance) > EPSILON))
  832.     {
  833.       Attenuation *= 2.0 / (1.0 + pow(Distance / Light->Fade_Distance, Light->Fade_Power));
  834.     }
  835.   }
  836.  
  837.   return(Attenuation);
  838. }
  839.